import type { AppointmentManagement } from '@shared/types/'
import type { BookingOptions, BookingOutcome, BookingStrategy } from './strategy'
import { getConfig } from '../config/index'
import { MultiprocessBookingService } from './multiprocess/multiprocess-booking-service'
import { PlaywrightBookingStrategy } from './playwright-strategy'
import { RequestBookingStrategy } from './request-strategy'

export type Mode = 'playwright' | 'request'

/**
 * 统一预约服务：
 * - 通过 mode 选择具体策略（Playwright / Request）。
 * - 对外暴露统一的 bookWith 接口，方便前端只传递 mode 与参数。
 * - 支持多进程模式（通过配置开关控制）。
 * - 后续若需要新增策略（如 Puppeteer），只需注册到 strategies。
 */
export class UnifiedBookingService {
  private strategies: Record<Mode, BookingStrategy>
  private multiprocessService?: MultiprocessBookingService

  constructor() {
    this.strategies = {
      playwright: new PlaywrightBookingStrategy(),
      request: new RequestBookingStrategy(),
    }
  }

  async bookWith(mode: Mode, appointment: AppointmentManagement, options?: BookingOptions): Promise<BookingOutcome> {
    // 检查是否启用多进程模式
    const config = getConfig()
    if (config.booking.multiprocess?.enabled) {
      // 使用多进程模式
      if (!this.multiprocessService) {
        this.multiprocessService = new MultiprocessBookingService(
          config.booking.multiprocess.maxWorkers || 50,
        )
        await this.multiprocessService.initialize()
      }
      return await this.multiprocessService.bookWith(mode, appointment, options)
    }
    else {
      // 使用原有单进程实现
      const strategy = this.strategies[mode]
      if (!strategy)
        return { success: false, error: `unsupported mode: ${mode}` }
      return await strategy.book(appointment, options)
    }
  }

  /**
   * 关闭服务（清理多进程资源）
   */
  async shutdown(): Promise<void> {
    if (this.multiprocessService) {
      await this.multiprocessService.shutdown()
      this.multiprocessService = undefined
    }
  }

  /**
   * 获取统计信息（多进程模式）
   */
  getStats() {
    if (this.multiprocessService) {
      return this.multiprocessService.getStats()
    }
    return null
  }
}

let svc: UnifiedBookingService | null = null
export function getUnifiedBookingService(): UnifiedBookingService {
  if (!svc)
    svc = new UnifiedBookingService()
  return svc
}
